// $Id: niohttpd.h 86 2011-05-04 17:33:43Z cedric.shih@gmail.com $
/*
 * Copyright (C) 2011 Cedric Shih <cedric.shih@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef NIOHTTPD_H_
#define NIOHTTPD_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/queue.h>
#include <sys/types.h>
#include <errno.h>

#include <nio.h>

const char *niohttpd_get_version(void);

enum niohttpd_errno {
	NIOHTTPD_EOK = 0, /**< Success. */
	NIOHTTPD_EINVAL = EINVAL, /**< Invalid argument(s). */
	NIOHTTPD_ENOMEM = ENOMEM, /**< Out of memory. */
	NIOHTTPD_ENOENT = ENOENT, /**< Session not pending. */
	NIOHTTPD_EEXIST = EEXIST, /**< Session pending. */
	NIOHTTPD_EAGAIN = EAGAIN, /**< Try again later. */
	NIOHTTPD_EINPROGRESS = EINPROGRESS, /**< Operation in progress. */
	NIOHTTPD_EIO = EIO, /**< I/O error. */
	NIOHTTPD_EPERM = EPERM, /**< Invalid argument(s). */
	NIOHTTPD_EUNKNOWN = 0x8000, /**< Unknown error. */
	NIOHTTPD_EBUFFER, /**< Buffering error. */
};

const char *niohttpd_strerror(enum niohttpd_errno err);

/**
 * @brief Set logger function.
 *
 * @param cb - logger function
 * @param buffer - buffer for message formatting
 * @param len - size of buffer
 * @see niohttpd_logger_cb
 */
void niohttpd_logger_set(niologger_cb cb, void *arg);

struct niohttpd_header {
	const char *name;
	const char *value;
	TAILQ_ENTRY(niohttpd_header) next;
};

TAILQ_HEAD(niohttpd_header_list, niohttpd_header);

struct niohttpd;

struct niohttpd *niohttpd_new(struct nioreactor *reactor);

void niohttpd_free(struct niohttpd *server);

struct in_addr;

int niohttpd_bind(struct niohttpd *server,
		struct in_addr *address, unsigned short port, int backlog);

struct niohttpd_servlet_factory;

int niohttpd_add_servlet(struct niohttpd *server, const char *uri,
		struct niohttpd_servlet_factory *factory, void *arg);

int niohttpd_del_servlet(struct niohttpd *server, const char *uri);

enum niohttpd_stream_event_type {
	NIOHTTPD_STREAM_EVENT_UNKNOWN,
	NIOHTTPD_STREAM_EVENT_OPEN,
	NIOHTTPD_STREAM_EVENT_CLOSING,
};

struct niohttpd_stream_event {
	enum niohttpd_stream_event_type type;
};

typedef void (*niohttpd_stream_cb)(
		struct niohttpd_stream_event *event, void *arg);

struct niohttp_headers;

int niohttpd_add_stream(struct niohttpd *server,
		const char *uri, struct niohttp_headers *headers,
		niohttpd_stream_cb cb, void *arg);

int niohttpd_del_stream(struct niohttpd *server, const char *uri);

int niohttpd_close_stream(struct niohttpd *server, const char *uri);

enum niohttpd_stream_qos_direction {
	NIOHTTPD_STREAM_QOS_FROM_OLDEST,
	NIOHTTPD_STREAM_QOS_FROM_LATEST,
};

struct niohttpd_stream_context {
	struct niohttp_headers *queued;
	struct niohttp_headers *incoming;
};

typedef struct niohttp_headers *(*niohttpd_stream_qos_cb)(
		const char *uri,
		enum niohttpd_stream_qos_direction dir,
		struct niohttpd_stream_context *ctx, void *cbarg);

int niohttpd_set_stream_qos(struct niohttpd *server, const char *uri,
		enum niohttpd_stream_qos_direction dir,
		niohttpd_stream_qos_cb cb, void *cbarg);

struct niohttp_headers;

struct niobuffer;

int niohttpd_push_stream(struct niohttpd *server, const char *uri,
		struct niohttp_headers *headers, struct niobuffer *content);

#ifdef __cplusplus
}
#endif

#endif /* NIOHTTPD_H_ */
